import { snippets } from "@/lib/generated/snippets";
import { Snippet } from "@/components/code";
import { Callout, Card, Cards, Steps, Tabs } from "nextra/components";
import UniversalTabs from "@/components/UniversalTabs";

# Declaring Your First Task

In Hatchet, the fundamental unit of invocable work is a [Task](#defining-a-task). Each task is an atomic function.

As we continue to build with Hatchet, we'll add additional configuration options to compose tasks into [DAG workflows](./dags.mdx) or [procedural child spawning](./child-spawning.mdx).

## Defining a Task

Start by declaring a task with a name. The task object can declare additional task-level configuration options which we'll cover later.

The returned object is an instance of the `Task` class, which is the primary interface for interacting with the task (i.e. [running](./run-with-results.mdx), [enqueuing](./run-no-wait.mdx), [scheduling](./scheduled-runs.mdx), etc).

<UniversalTabs items={["Python", "Typescript", "Go"]}>
  <Tabs.Tab title="Python">

<Snippet src={snippets.python.quickstart.workflows.first_task.simple_task} />
</Tabs.Tab>
<Tabs.Tab title="Typescript">
<Snippet src={snippets.typescript.simple.workflow.declaring_a_task} />
</Tabs.Tab>
<Tabs.Tab title="Go">
<Snippet src={snippets.go.simple.main.declaring_a_task} />
</Tabs.Tab>
</UniversalTabs>

## Running a Task

With your task defined, you can import it wherever you need to use it and invoke it with the `run` method.

<Callout type="warning">
  NOTE: You must first [register the task on a worker](./workers.mdx) before you
  can run it. Calling `your_task.run` will enqueue a task to be executed by a
  worker but it will wait indefinitely for the task to be executed.
</Callout>

<UniversalTabs items={["Python", "Typescript", "Go"]}>
  <Tabs.Tab title="Python">

<Snippet src={snippets.python.quickstart.run.run_a_task} />

</Tabs.Tab>
<Tabs.Tab title="Typescript">
<Snippet src={snippets.typescript.simple.run.running_a_task} />
</Tabs.Tab>
<Tabs.Tab title="Go">
<Snippet src={snippets.go.simple.main.running_a_task} />
</Tabs.Tab>
</UniversalTabs>

There are many ways to run a task, including:

- [Running a task with results](./run-with-results.mdx)
- [Enqueuing a task](./run-no-wait.mdx)
- [Scheduling a task](./scheduled-runs.mdx)
- [Scheduling a task with a cron schedule](./cron-runs.mdx)
- [Event-driven task execution](./run-on-event.mdx)

Now that you have defined a complete task, you can move on to [creating a worker to execute the task](./workers.mdx).
